# encoding: utf-8
# @File  : test04.py
# @Author: wu shaofan
# @Date  :  2024/02/16
# @Desc : 京东滑动块破解

import base64
import os
import time
import cv2
import pyautogui
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
import conftest


def FindPic(target='big.png', template='small.png'):
    target_rgb = cv2.imread(target)
    target_gray = cv2.cvtColor(target_rgb, cv2.COLOR_RGB2GRAY)
    template_rgb = cv2.imread(template, 0)
    res = cv2.matchTemplate(target_gray, template_rgb, cv2.TM_CCOEFF_NORMED)
    value = cv2.minMaxLoc(res)
    print(value)
    return value[2][0]

chrome_driver_path = conftest.BASE_DIR + '/tool/chromedriver.exe'

# 创建 ChromeOptions 对象
options = Options()
options.add_experimental_option("excludeSwitches", ["enable-logging"])

# 创建 Chrome WebDriver 服务
service = Service(chrome_driver_path)
# 创建 Chrome WebDriver 实例
driver = webdriver.Chrome(service=service, options=options)
# 窗口最大化
driver.maximize_window()
# 打开网页
url = "https://passport.jd.com/new/login.aspx?ReturnUrl=https%3A%2F%2Fwww.jd.com%2F"
# 打开网址
driver.get(url)
driver.find_element("id", "loginname").send_keys("18325539630")
driver.find_element("id", "nloginpwd").send_keys("123456")
driver.find_element("id", "loginsubmit").click()

'''失败重试'''
while True:

    '''保存大图和小图'''
    # 保存获取到的图片
    loc = ("css selector", 'div.JDJRV-bigimg>img')
    ec = WebDriverWait(driver, timeout=3, poll_frequency=0.5).until(lambda x:x.find_element(*loc))
    big_url = ec.get_attribute('src')

    # # 当验证码大小为0 时候就是破解成功了，就不用重试了
    # size = WebDriverWait(driver, timeout=3, poll_frequency=0.5).until(lambda x: x.find_element(*loc)).size
    # if size.get('width') < 1:
    #     break

    small_url = driver.find_element("css selector", 'div.JDJRV-smallimg>img').get_attribute('src')

    # 正则表达式提取需要的部分
    # big_base64_str = re.sub(r'data:[a-z]*/[a-z]*;base64,', '', big_url)
    # small_base64_str = re.sub(r'data:[a-z]*/[a-z]*;base64,', '', small_url)

    # 利用split的来进行数据的分割也可以
    big_base64_str = big_url.split(',')[-1]
    small_base64_str = small_url.split(',')[-1]

    # 图片的二进制的数据
    big_binary_content = base64.b64decode(big_base64_str)
    small_binary_content = base64.b64decode(small_base64_str)

    # 判断文件夹是否存在不存在则创建'
    os.makedirs('./image/', exist_ok=True)
    #  保存图片
    with open('./image/big.png', mode='wb') as f:
        f.write(big_binary_content)
    with open('./image/small.png', mode='wb') as f:
        f.write(small_binary_content)

    '''小图在大图中的缺口位置'''
    a = FindPic('./image/big.png', './image/small.png')
    print("本地图片需要滑动的距离：{}".format(a))

    '''换算距离'''
    distance = a * 243 // 360
    print("seleium库相对于网页需要滑动的距离：{}".format(distance))

    distance = a * 243 * 1.99 // 360
    print("pyautogui库相对于窗口需要滑动的距离：{}".format(distance))

    '''拖动滑块'''
    # 使用pyautogui库来实现拖动滑块
    # 获取小滑块的位置
    lo = driver.find_element("css selector", 'div.JDJRV-smallimg>img').location
    # 如print(lo)   {'x': 849, 'y': 286} 相对于网页，不是浏览器窗口

    x = lo['x'] * 1.99 + 17
    y = lo['y']*1.99 + 160 + 17 +80

    #  定位鼠标到指定小滑块中心点位置，然后按下
    pyautogui.mouseDown(x, y)
    #  滑过头
    pyautogui.moveTo(x+distance+20, y+10, duration=0.3)
    #  滑回来
    pyautogui.moveTo(x+distance-10, y-5, duration=0.3)
    # 滑到指定位置
    pyautogui.moveTo(x+distance, y, duration=0.3)
    # 松开鼠标
    pyautogui.mouseUp()
    time.sleep(2)

    '''失败重试'''
    # 当验证码大小为0 时候就是破解成功了，就不用重试了
    size = WebDriverWait(driver, timeout=3, poll_frequency=0.5).until(lambda x: x.find_element(*loc)).size
    if size.get('width') < 1:
        break
